package com.lyn.mmkv;


import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import com.tencent.mmkv.MMKV;

import java.lang.reflect.Field;

public class MMKVManager {

    private static final String TAG = "MMKVManager";
    private static final String FILE_NAME = "setting";
    private final MMKV mmkv;
    private Object keyObject;

    private static class PreferenceUtilClassInstance {
        private static final MMKVManager instance = new MMKVManager();
    }

    public static MMKVManager getInstance() {
        return PreferenceUtilClassInstance.instance;
    }

    public MMKVManager() {
        mmkv = MMKV.mmkvWithID(FILE_NAME);
    }

    public void setKeyObject(Object keyObject) {
        this.keyObject = keyObject;
    }

    public void clear() {
        mmkv.edit().clear().apply();
    }

    public void setString(String key, String value) {
        try {
            SharedPreferences.Editor editor = mmkv.edit();
            editor.putString(key, value);
            editor.apply();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void setInt(String key, int value) {
        try {
            SharedPreferences.Editor editor = mmkv.edit();
            editor.putInt(key, value);
            editor.apply();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void setFloat(String key, float value) {
        try {
            SharedPreferences.Editor editor = mmkv.edit();
            editor.putFloat(key, value);
            editor.apply();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void setLong(String key, long value) {
        try {
            SharedPreferences.Editor editor = mmkv.edit();
            editor.putLong(key, value);
            editor.apply();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void setBoolean(String key, boolean value) {
        try {
            SharedPreferences.Editor editor = mmkv.edit();
            editor.putBoolean(key, value);
            editor.apply();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public String getString(String key) {
        String defaultValue = null;
        Class<?> aClass = keyObject.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            boolean annotationPresent = field.isAnnotationPresent(StringDefaultValues.class);
            if (annotationPresent) {
                Object keyObject = null;
                try {
                    keyObject = field.get(aClass);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                String keyName = (String) keyObject;
                assert keyName != null;
                if (keyName.equals(key)) {
                    StringDefaultValues stringDefaultValues = field.getAnnotation(StringDefaultValues.class);
                    assert stringDefaultValues != null;
                    defaultValue = stringDefaultValues.value();
                    break;
                }
            }
        }
        return mmkv.getString(key, defaultValue);
    }


    public boolean getBoolean(String key) {
        boolean defaultValue = false;
        Class<? extends Object> keyClass = keyObject.getClass();
        Field[] declaredFields = keyClass.getDeclaredFields();
        for (Field field : declaredFields) {
            boolean annotationPresent = field.isAnnotationPresent(BooleanDefaultValues.class);
            if (annotationPresent) {
                Object keyObject = null;
                try {
                    keyObject = field.get(keyClass);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                String keyName = (String) keyObject;
                assert keyName != null;
                if (keyName.equals(key)) {
                    BooleanDefaultValues booleanDefaultValues = field.getAnnotation(BooleanDefaultValues.class);
                    assert booleanDefaultValues != null;
                    defaultValue = booleanDefaultValues.value();
                    break;
                }
            }
        }
        return mmkv.getBoolean(key, defaultValue);
    }

    public int getInt(String key) {
        int defaultValue = 0;
        Class<? extends Object> aClass = keyObject.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            boolean annotationPresent = field.isAnnotationPresent(IntDefaultValues.class);
            if (annotationPresent) {
                Object keyObject = null;
                try {
                    keyObject = field.get(aClass);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                String keyName = (String) keyObject;
                assert keyName != null;
                if (keyName.equals(key)) {
                    IntDefaultValues intDefaultValues = field.getAnnotation(IntDefaultValues.class);
                    assert intDefaultValues != null;
                    defaultValue = intDefaultValues.value();
                    break;
                }
            }
        }
        return mmkv.getInt(key, defaultValue);
    }

    public long getLong(String key) {
        long defaultValue = 0L;
        Class<?> aClass = keyObject.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            boolean annotationPresent = field.isAnnotationPresent(LongDefaultValues.class);
            if (annotationPresent) {
                Object keyObject = null;
                try {
                    keyObject = field.get(aClass);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                String keyName = (String) keyObject;
                assert keyName != null;
                if (keyName.equals(key)) {
                    LongDefaultValues longDefaultValues = field.getAnnotation(LongDefaultValues.class);
                    assert longDefaultValues != null;
                    defaultValue = longDefaultValues.value();
                    break;
                }
            }
        }
        return mmkv.getLong(key, defaultValue);
    }

    public float getFloat(String key) {
        float defaultValue = 0f;
        Class<?> aClass = keyObject.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            boolean annotationPresent = field.isAnnotationPresent(FloatDefaultValues.class);
            if (annotationPresent) {
                Object keyObject = null;
                try {
                    keyObject = field.get(aClass);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                String keyName = (String) keyObject;
                assert keyName != null;
                if (keyName.equals(key)) {
                    FloatDefaultValues floatDefaultValues = field.getAnnotation(FloatDefaultValues.class);
                    assert floatDefaultValues != null;
                    defaultValue = floatDefaultValues.value();
                    break;
                }
            }
        }
        return mmkv.getFloat(key, defaultValue);
    }


}
